<?php

declare(strict_types=1);

namespace App\CustHub\Service;

use App\CustHub\Amqp\Producers\SyncTaskProducers;
use App\CustHub\Constants\SyncTaskStatusConstants;
use App\CustHub\Constants\SyncTaskTypeConstants;
use App\CustHub\Dto\SyncTaskDto;
use App\CustHub\Mapper\ChSyncTaskMapper;
use App\CustHub\Model\ChSyncTask;
use Carbon\Carbon;
use Hyperf\Amqp\Producer;
use Mine\Abstracts\AbstractService;
use Mine\Exception\NormalStatusException;
use Mine\MineModel;
use function Hyperf\Collection\data_get;

class ChSyncTaskService extends AbstractService
{
    public $mapper;

    public function __construct(ChSyncTaskMapper $mapper)
    {
        $this->mapper = $mapper;
    }


    public function list(array $params): array
    {
        $pageSize = $params['page_size'] ?? MineModel::PAGE_SIZE;
        $type = data_get($params, 'type', SyncTaskTypeConstants::PERSONAL_TAG);

        $robotId = data_get($params, 'robot_id');
        $status = data_get($params, 'status');
        $startTime = data_get($params, 'start_time');
        $endTime = data_get($params, 'end_time');

        if (!empty($startTime) && !empty($endTime)) {
            $startTime = strtotime($startTime);
            $endTime = Carbon::now()->timestamp(strtotime($endTime))->endOfDay()->timestamp;
        }

        $paginate = ChSyncTask::query()
            ->select(['id', 'robot_id', 'status', 'type', 'start_time', 'created_at'])
            ->with(['robot' => function ($query) {
                $query->select(['id', 'nickname', 'avatar', 'user_id', 'corp_name']);
            }])
            ->where('main_uid', $params['main_uid'])
            ->where('type', $type)
            ->when(!empty($robotId), function ($query) use ($robotId) {
                $query->where('robot_id', $robotId);
            })
            ->when(filled($status), function ($query) use ($status) {
                $query->where('status', $status);
            })
            ->when(!empty($startTime) && !empty($endTime), function ($query) use ($startTime, $endTime) {
                $query->whereBetween('start_time', [$startTime, $endTime]);
            })
            ->orderBy('created_at', 'desc')
            ->paginate((int)$pageSize);

        $paginate->getCollection()->transform(function ($item) {
            $item->start_time_text = empty($item->start_time) ? '' : datetime($item->start_time);
            $item->end_time_text = empty($item->end_time) ? '' : datetime($item->end_time);
            $item->status_text = SyncTaskStatusConstants::getMessage($item->status);
            return $item;
        });

        return $this->mapper->setPaginate($paginate);
    }

    /**
     * 删除任务
     * @param array $params
     * @return bool|int|mixed|null
     * @throws \Exception
     */
    public function del(array $params): mixed
    {
        $ids = json_decode($params['ids'],true);
        return ChSyncTask::query()
            ->whereIn('id', $ids)
            ->where('main_uid', $params['main_uid'])
            ->delete();
    }

    public function again(array $params): bool
    {
        $ids = json_decode($params['ids'],true);
        $list = ChSyncTask::query()
            ->whereIn('id', $ids)
            ->where('main_uid', $params['main_uid'])
            ->get();

        foreach ($list as $info){
            if (!in_array($info->status, SyncTaskStatusConstants::getInProcessStatus())) {
//                throw new NormalStatusException('任务进行中~');
                continue;
            }
            $currentSeq = 0;
            if (in_array($info->type, SyncTaskTypeConstants::getNeedCurrentSeqType())) {
                $isCorp = false;
                switch ($info->type) {
                    case SyncTaskTypeConstants::CORP_TAG:
                        $id = $info->corp_id;
                        $isCorp = true;
                        break;
                    case SyncTaskTypeConstants::PERSONAL_TAG:
                        $id = $info->robot_id;
                        break;
                    default:
                        $id = 0;
                        break;
                }
                $currentSeq = $this->mapper->getLatestCurrentSeq($id, $info->type, $isCorp);
            }

            $info->status = SyncTaskStatusConstants::WAITING;
            $info->save();

            container()->get(Producer::class)->produce(new SyncTaskProducers(new SyncTaskDto(
                taskId: $info->id,
                type: $info->type,
                className: __CLASS__,
                method: 'syncTag',
                currentSeq: $currentSeq
            )));
        }
        return true;
    }
}